#--------------------------------------------------------------
# Always use full RPATH (differentiating between the build and install trees)

# use, i.e. don't skip the full RPATH for the build tree
set(CMAKE_SKIP_BUILD_RPATH  FALSE)

# when building, don't use the install RPATH already
# (but later on when installing)
set(CMAKE_BUILD_WITH_INSTALL_RPATH FALSE)

set(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/lib")

# add the automatically determined parts of the RPATH
# which point to directories outside the build tree to the install RPATH
set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)

# the RPATH to be used when installing, but only if it's not a system directory
list(FIND CMAKE_PLATFORM_IMPLICIT_LINK_DIRECTORIES "${CMAKE_INSTALL_PREFIX}/lib" isSystemDir)
if("${isSystemDir}" STREQUAL "-1")
   set(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/lib")
endif("${isSystemDir}" STREQUAL "-1")

#--------------------------------------------------------------

# Enable creation of "application bundles" on MacOSX, necessary for Irrlicht-based demos.
# For simplicity and consistency, we enable here MACOSX_BUNDLE for all subsequent programs.

if(APPLE)
    set(CMAKE_MACOSX_BUNDLE OFF)
    set(MACOSX_BUNDLE_INFO_PLIST "${PROJECT_SOURCE_DIR}/cmake/MacOSXBundleInfo.plist.in")
endif()

#--------------------------------------------------------------

# Convenience function to build and install demos from a list
function(build_demos DEMOS LIBS)
    
    # Get optional list of additional files
    if(${ARGC} GREATER 2)
      set(EXTRA_FILES ${ARGV2})
    else()
      set(EXTRA_FILES "")
    endif()
    
    # Build all demos in the list DEMOS, linking to LIBS
    foreach(PROGRAM ${DEMOS})
        add_executable(${PROGRAM} ${PROGRAM}.cpp ${EXTRA_FILES})
        source_group(""  FILES ${PROGRAM}.cpp ${EXTRA_FILES})
    
        set_target_properties(${PROGRAM} PROPERTIES FOLDER demos)
        if(APPLE)
          set_target_properties(${PROGRAM} PROPERTIES MACOSX_BUNDLE_INFO_PLIST ${MACOSX_BUNDLE_INFO_PLIST})
        endif()
        if(MSVC)
          set_target_properties(${PROGRAM} PROPERTIES VS_DEBUGGER_WORKING_DIRECTORY "$<TARGET_FILE_DIR:${PROGRAM}>")
          set_target_properties(${PROGRAM} PROPERTIES MSVC_RUNTIME_LIBRARY ${CH_MSVC_RUNTIME_LIBRARY})
        endif()

        target_include_directories(${PROGRAM} PRIVATE "${CMAKE_SOURCE_DIR}/src/chrono_thirdparty")
        target_link_libraries(${PROGRAM} ${LIBS})
        
        install(TARGETS ${PROGRAM} CONFIGURATIONS Release DESTINATION ${CH_INSTALL_DEMO})
    endforeach()

endfunction()

#--------------------------------------------------------------

message(STATUS "\n==== Demo programs ====\n")

option(BUILD_DEMOS_BASE "Build demo programs for base Chrono module" TRUE)
mark_as_advanced(FORCE BUILD_DEMOS_BASE)
if(BUILD_DEMOS_BASE)
    add_subdirectory(core)
endif()

option(BUILD_DEMOS_FEA "Build demo programs for FEA" TRUE)
mark_as_advanced(FORCE BUILD_DEMOS_FEA)
if(BUILD_DEMOS_FEA)
    add_subdirectory(fea)
endif()

option(BUILD_DEMOS_ROBOT "Build robot demo programs" ON)
mark_as_advanced(FORCE BUILD_DEMOS_ROBOT)
if(BUILD_DEMOS_ROBOT)
    add_subdirectory(robot)
endif()

option(BUILD_DEMOS_COSIMULATION "Build socket communication demo programs" TRUE)
mark_as_advanced(FORCE BUILD_DEMOS_COSIMULATION)
if(BUILD_DEMOS_COSIMULATION)
    add_subdirectory(cosimulation)
endif()

if(CH_ENABLE_MODULE_IRRLICHT OR CH_ENABLE_MODULE_VSG)
    option(BUILD_DEMOS_MBS "Build demo programs for MBS module" TRUE)
    mark_as_advanced(FORCE BUILD_DEMOS_MBS)
    if(BUILD_DEMOS_MBS)
      add_subdirectory(mbs)
    endif()
endif()

if(CH_ENABLE_MODULE_PARSERS)
    option(BUILD_DEMOS_PARSERS "Build demo programs for Parsers module" TRUE)
    mark_as_advanced(FORCE BUILD_DEMOS_PARSERS)
    if(BUILD_DEMOS_PARSERS)
      add_subdirectory(yaml)
      add_subdirectory(parsers)
    endif()    
endif()

if(CH_ENABLE_MODULE_IRRLICHT)
    option(BUILD_DEMOS_IRRLICHT "Build demo programs for Irrlicht module" TRUE)
    mark_as_advanced(FORCE BUILD_DEMOS_IRRLICHT)
    if(BUILD_DEMOS_IRRLICHT)
        add_subdirectory(irrlicht)
    endif()
endif()

if(CH_ENABLE_MODULE_VSG)
    option(BUILD_DEMOS_VSG "Build demo programs for VSG module" TRUE)
    mark_as_advanced(FORCE BUILD_DEMOS_VSG)
    if(BUILD_DEMOS_VSG)
        add_subdirectory(vsg)
    endif()
endif()

if(CH_ENABLE_MODULE_MATLAB)
    option(BUILD_DEMOS_MATLAB "Build demo programs for Matlab module" TRUE)
    mark_as_advanced(FORCE BUILD_DEMOS_MATLAB)
    if(BUILD_DEMOS_MATLAB)
        add_subdirectory(matlab)
    endif()
endif()

if(CH_ENABLE_MODULE_MUMPS)
    option(BUILD_DEMOS_MUMPS "Build demo programs for MUMPS module" TRUE)
    mark_as_advanced(FORCE BUILD_DEMOS_MUMPS)
    if(BUILD_DEMOS_MUMPS)
      add_subdirectory(mumps)
    endif()
endif()

if(CH_ENABLE_MODULE_CASCADE)
    option(BUILD_DEMOS_CASCADE "Build demo programs for Cascade module" TRUE)
    mark_as_advanced(FORCE BUILD_DEMOS_CASCADE)
    if(BUILD_DEMOS_CASCADE)
        add_subdirectory(cascade)
    endif()
endif()

if(CH_ENABLE_MODULE_DEM)
    option(BUILD_DEMOS_DEM "Build demo programs for DEM module" TRUE)
    mark_as_advanced(FORCE BUILD_DEMOS_DEM)
    if(BUILD_DEMOS_DEM)
        add_subdirectory(dem)
    endif()
endif()

if(CH_ENABLE_MODULE_POSTPROCESS)
    option(BUILD_DEMOS_POSTPROCESS "Build demo programs for Postprocess module" TRUE)
    mark_as_advanced(FORCE BUILD_DEMOS_POSTPROCESS)
    if(BUILD_DEMOS_POSTPROCESS)
        add_subdirectory(postprocess)
    endif()
endif()

if(CH_ENABLE_MODULE_MULTICORE)
    option(BUILD_DEMOS_MULTICORE "Build demo programs for Multicore module" TRUE)
    mark_as_advanced(FORCE BUILD_DEMOS_MULTICORE)
    if(BUILD_DEMOS_MULTICORE)
      add_subdirectory(multicore)
    endif()
endif()

if(CH_ENABLE_MODULE_VEHICLE AND CH_ENABLE_MODULE_VEHICLE_MODELS)
    option(BUILD_DEMOS_VEHICLE "Build demo programs for Vehicle module" TRUE)
    mark_as_advanced(FORCE BUILD_DEMOS_VEHICLE)
    if(BUILD_DEMOS_VEHICLE)
      add_subdirectory(vehicle)
    endif()
endif()

if(CH_ENABLE_MODULE_FSI)
    option(BUILD_DEMOS_FSI "Build demo programs for FSI module" TRUE)
    mark_as_advanced(FORCE BUILD_DEMOS_FSI)
    if(BUILD_DEMOS_FSI)
      add_subdirectory(fsi)
    endif()
endif()

if(CH_ENABLE_MODULE_SENSOR)
    option(BUILD_DEMOS_SENSOR "Build demo programs for Sensor module" TRUE)
    mark_as_advanced(FORCE BUILD_DEMOS_SENSOR)
    if(BUILD_DEMOS_SENSOR)
      add_subdirectory(sensor)
    endif()
endif()

if(CH_ENABLE_MODULE_SYNCHRONO)
    option(BUILD_DEMOS_SYNCHRONO "Build demo programs for SynChrono module" TRUE)
    mark_as_advanced(FORCE BUILD_DEMOS_SYNCHRONO)
    if(BUILD_DEMOS_SYNCHRONO)
      add_subdirectory(synchrono)
    endif()
endif()

if(CH_ENABLE_MODULE_ROS)
	option(BUILD_DEMOS_ROS "Build demo programs for ROS module" TRUE)
	mark_as_advanced(FORCE BUILD_DEMOS_ROS)
	if(BUILD_DEMOS_ROS)
  		add_subdirectory(ros)
  	endif()
endif()

if(CH_ENABLE_MODULE_MODAL)
    option(BUILD_DEMOS_MODAL "Build demo programs for Modal module" TRUE)
    mark_as_advanced(FORCE BUILD_DEMOS_MODAL)
    if(BUILD_DEMOS_MODAL)
      add_subdirectory(modal)
    endif()
endif()

if(CH_ENABLE_MODULE_FMI)
    option(BUILD_DEMOS_FMI "Build demo programs for FMI support" TRUE)
    mark_as_advanced(FORCE BUILD_DEMOS_FMI)
    if(BUILD_DEMOS_FMI)
      add_subdirectory(fmi)
    endif()
endif()

if(CH_ENABLE_MODULE_PERIDYNAMICS)
    option(BUILD_DEMOS_PERIDYNAMICS "Build demo programs for Peridynamics module" TRUE)
    mark_as_advanced(FORCE BUILD_DEMOS_PERIDYNAMICS)
    if(BUILD_DEMOS_PERIDYNAMICS)
        add_subdirectory(peridynamics)
    endif()
endif()

if(CH_ENABLE_MODULE_CSHARP)
    option(BUILD_DEMOS_CSHARP "Build demo programs for Csharp module" TRUE)
    mark_as_advanced(FORCE BUILD_DEMOS_CSHARP)
    if(BUILD_DEMOS_CSHARP)
       # Configure the standalone C# demo sub-build, forwarding the wrapper flag so
       # it knows when chrono_csharp_wrapper.dll should be referenced instead of raw .cs files
       add_custom_target(Csharp_demos ALL
             COMMAND ${CMAKE_COMMAND} -S ${CMAKE_CURRENT_SOURCE_DIR}/csharp -B ${PROJECT_BINARY_DIR}/csharp
                 -DCMAKE_RUNTIME_OUTPUT_DIRECTORY:PATH=${CMAKE_RUNTIME_OUTPUT_DIRECTORY}
                 -DCH_ENABLE_MODULE_VEHICLE:BOOL=${CH_ENABLE_MODULE_VEHICLE}
                 -DCH_ENABLE_MODULE_SENSOR:BOOL=${CH_ENABLE_MODULE_SENSOR}
                 -DCH_ENABLE_MODULE_POSTPROCESS:BOOL=${CH_ENABLE_MODULE_POSTPROCESS}
                 -DCH_ENABLE_MODULE_IRRLICHT:BOOL=${CH_ENABLE_MODULE_IRRLICHT}
                 -DCH_ENABLE_MODULE_VSG:BOOL=${CH_ENABLE_MODULE_VSG}
                 -DCH_USE_CSHARP_WRAPPER:BOOL=${CH_USE_CSHARP_WRAPPER}
             COMMAND ${CMAKE_COMMAND} --build ${PROJECT_BINARY_DIR}/csharp --config $<CONFIG>)
       add_dependencies(Csharp_demos Chrono_csharp_core)
       add_dependencies(Csharp_demos Chrono_csharp_robot)
       if(CH_USE_CSHARP_WRAPPER)
          add_dependencies(Csharp_demos Chrono_csharp_wrapper)
          endif()
       if(CH_ENABLE_MODULE_VEHICLE)
          add_dependencies(Csharp_demos Chrono_csharp_vehicle)
       endif()
       if(CH_ENABLE_MODULE_SENSOR)
          add_dependencies(Csharp_demos Chrono_csharp_sensor)
       endif()
       if(CH_ENABLE_MODULE_POSTPROCESS)
          add_dependencies(Csharp_demos Chrono_csharp_postprocess)
       endif()
       if(CH_ENABLE_MODULE_IRRLICHT)
          add_dependencies(Csharp_demos Chrono_csharp_irrlicht)
       endif()
       if(CH_ENABLE_MODULE_VSG)
          add_dependencies(Csharp_demos Chrono_csharp_vsg)
       endif()
    endif()
endif()
